/**
 * @file protocol_validator.h
 * @brief 104协议验证器头文件
 * @details 本文件定义了104协议的协议验证器功能，包括APDU验证、ASDU验证、序列号
 *          验证、协议状态管理等核心功能。提供完整的协议验证流程，确保接收到的
 *          协议数据符合104协议规范，包含完整的错误处理和状态管理。支持I格式、
 *          S格式、U格式APDU的验证和各种类型ASDU的验证。
 * 
 * @author zyb
 * @date 2025-10-16
 * @version 1.0
 * 
 * @note 协议验证器维护序列号状态，确保协议数据的有序性
 * @warning 验证器需要正确管理序列号，避免序列号错误导致的通信中断
 * 
 * @see protocol_validator.c
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

#ifndef PROTOCOL_VALIDATOR_H
#define PROTOCOL_VALIDATOR_H

#include "protocol_types.h"
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== 前向声明 ==================== */

/**
 * @brief 协议验证器结构体
 */
typedef struct protocol_validator protocol_validator_t;

/* ==================== 验证结果定义 ==================== */

/**
 * @brief 协议验证结果结构体
 * @details 包含协议验证的完整结果信息，包括验证是否成功、错误码和错误消息。
 *          用于向调用者提供详细的验证结果反馈。
 */
typedef struct {
    bool is_valid;          /* 验证是否成功，true表示有效，false表示无效 */
    protocol_error_t error; /* 错误码，当is_valid为false时使用 */
    const char* message;    /* 错误消息字符串，提供详细的错误描述 */
} validation_result_t;

/* ==================== APDU验证 ==================== */


/**
 * @brief 验证APDU启动字符
 * @details 验证APDU的启动字符是否为有效的104协议启动字符（0x68）。
 *          启动字符是APDU的第一个字节，用于标识APDU的开始。
 * 
 * @param start_char 启动字符值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示启动字符有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 104协议规定启动字符必须为0x68
 * @warning 无效的启动字符会导致整个APDU被丢弃
 * @see validation_result_t
 * @see validate_apdu_format
 * @see validate_apdu_length
 */
validation_result_t validate_apdu_start_char(u8 start_char);

/**
 * @brief 验证APDU长度
 * @details 验证APDU的长度字段是否在有效范围内。104协议规定APDU长度
 *          必须在4-253字节之间（不包括启动字符和长度字段本身）。
 * 
 * @param length APDU长度字段值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示长度有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 104协议规定APDU长度范围为4-253字节
 * @warning 长度超出范围会导致APDU被丢弃
 * @see validation_result_t
 * @see validate_apdu_format
 * @see validate_apdu_start_char
 */
validation_result_t validate_apdu_length(u8 length);

/**
 * @brief 验证I格式控制域
 * @details 验证I格式APDU的控制域是否符合104协议规范。I格式用于传输信息对象，
 *          包含发送序列号、接收序列号等信息。验证包括控制域格式、序列号范围等。
 * 
 * @param control 控制域数据，4字节数组，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示控制域有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note I格式控制域包含发送和接收序列号
 * @warning 序列号必须在有效范围内（0-32767）
 * @see validation_result_t
 * @see validate_s_format_control
 * @see validate_u_format_control
 */
validation_result_t validate_i_format_control(const u8 control[4]);

/**
 * @brief 验证S格式控制域
 * @details 验证S格式APDU的控制域是否符合104协议规范。S格式用于传输确认信息，
 *          只包含接收序列号，用于确认已接收的I格式APDU。验证包括控制域格式、
 *          序列号范围等。
 * 
 * @param control 控制域数据，4字节数组，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示控制域有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note S格式控制域只包含接收序列号
 * @warning 序列号必须在有效范围内（0-32767）
 * @see validation_result_t
 * @see validate_i_format_control
 * @see validate_u_format_control
 */
validation_result_t validate_s_format_control(const u8 control[4]);

/**
 * @brief 验证U格式控制域
 * @details 验证U格式APDU的控制域是否符合104协议规范。U格式用于传输控制命令，
 *          如STARTDT、STOPDT、TESTFR等。验证包括控制域格式、功能码等。
 * 
 * @param control 控制域数据，4字节数组，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示控制域有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note U格式控制域包含功能码信息
 * @warning 功能码必须为有效的104协议功能码
 * @see validation_result_t
 * @see validate_i_format_control
 * @see validate_s_format_control
 */
validation_result_t validate_u_format_control(const u8 control[4]);

/* ==================== ASDU验证 ==================== */

/**
 * @brief 验证ASDU格式
 * @details 验证ASDU（应用服务数据单元）的基本格式是否正确，包括类型标识、
 *          可变结构限定词、传输原因、公共地址等基本结构的验证。
 * 
 * @param data ASDU数据缓冲区，不能为NULL
 * @param length 数据长度，必须大于等于最小ASDU长度
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示格式正确，false表示格式错误
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数只验证基本格式，不验证具体内容
 * @warning 数据长度必须大于等于最小ASDU长度
 * @see validation_result_t
 * @see validate_asdu_type_id
 * @see validate_asdu_cause
 */
validation_result_t validate_asdu_format(const u8* data, u32 length);

/**
 * @brief 验证ASDU类型标识
 * @details 验证ASDU的类型标识是否为有效的104协议类型标识。类型标识用于
 *          标识ASDU中包含的信息类型，如遥测、遥信、遥控等。
 * 
 * @param type_id 类型标识值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示类型标识有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 类型标识必须在104协议规定的有效范围内
 * @warning 无效的类型标识会导致ASDU被丢弃
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_vsq
 */
protocol_error_t validate_type_id(u8 type_id);

/**
 * @brief 验证ASDU可变结构限定词
 * @details 验证ASDU的可变结构限定词是否符合104协议规范。可变结构限定词用于
 *          指示ASDU中包含的信息对象数量和结构类型。
 * 
 * @param vsq 可变结构限定词值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示可变结构限定词有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 可变结构限定词包含信息对象数量信息
 * @warning 信息对象数量必须在有效范围内
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_type_id
 */
validation_result_t validate_vsq(u8 vsq);

/**
 * @brief 验证ASDU传送原因
 * @details 验证ASDU的传送原因是否符合104协议规范。传送原因用于指示
 *          信息传输的原因，如周期传输、突发传输、总召唤等。
 * 
 * @param cot 传送原因值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示传送原因有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 传送原因必须在104协议规定的有效范围内
 * @warning 无效的传送原因会导致ASDU被丢弃
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_common_address
 */
validation_result_t validate_cot(u16 cot);

/**
 * @brief 验证ASDU公共地址
 * @details 验证ASDU的公共地址是否符合104协议规范。公共地址用于标识
 *          通信的源站或目的站，是ASDU的重要组成部分。
 * 
 * @param common_addr 公共地址值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示公共地址有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 公共地址必须在104协议规定的有效范围内
 * @warning 无效的公共地址会导致ASDU被丢弃
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_cot
 */
protocol_error_t validate_common_address(u16 common_addr);

/**
 * @brief 验证ASDU信息对象地址
 * @details 验证ASDU中的信息对象地址是否符合104协议规范。信息对象地址用于
 *          标识具体的信息对象，如遥测点、遥信点等。
 * 
 * @param info_addr 信息对象地址值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示信息对象地址有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 信息对象地址必须在104协议规定的有效范围内
 * @warning 无效的信息对象地址会导致ASDU被丢弃
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_common_address
 */
validation_result_t validate_info_address(info_addr_t info_addr);

/* ==================== 数据验证 ==================== */

/**
 * @brief 验证单点信息品质描述词
 * @details 验证单点信息品质描述词（SIQ）是否符合104协议规范。SIQ用于
 *          描述单点信息（遥信）的品质，包括有效性、封锁、替换、溢出等状态。
 * 
 * @param siq 单点信息品质描述词指针，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示品质描述词有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note SIQ包含单点信息的状态和品质信息
 * @warning 无效的品质描述词会导致信息对象被丢弃
 * @see validation_result_t
 * @see validate_diq
 * @see validate_qds_validator
 */
protocol_error_t validate_siq(const siq_t* siq);

/**
 * @brief 验证双点信息品质描述词
 * @details 验证双点信息品质描述词（DIQ）是否符合104协议规范。DIQ用于
 *          描述双点信息（遥信）的品质，包括有效性、封锁、替换、溢出等状态。
 * 
 * @param diq 双点信息品质描述词指针，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示品质描述词有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note DIQ包含双点信息的状态和品质信息
 * @warning 无效的品质描述词会导致信息对象被丢弃
 * @see validation_result_t
 * @see validate_siq
 * @see validate_qds_validator
 */
protocol_error_t validate_diq(const diq_t* diq);

/**
 * @brief 验证品质描述词
 * @details 验证品质描述词（QDS）是否符合104协议规范。QDS用于
 *          描述测量值的品质，包括有效性、封锁、替换、溢出等状态。
 * 
 * @param qds 品质描述词指针，不能为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示品质描述词有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note QDS包含测量值的品质信息
 * @warning 无效的品质描述词会导致信息对象被丢弃
 * @see validation_result_t
 * @see validate_siq
 * @see validate_diq
 */
validation_result_t validate_qds_validator(const qds_t* qds);

/**
 * @brief 验证时间戳（使用protocol_types.h中的validate_cp56time2a函数）
 * @param time 时间戳
 * @return 验证结果
 */

/**
 * @brief 验证归一化值
 * @details 验证归一化值是否符合104协议规范。归一化值用于表示
 *          测量值的标准化数值，通常在-1.0到1.0之间。
 * 
 * @param value 归一化值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示归一化值有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 归一化值通常在-1.0到1.0之间
 * @warning 超出范围的归一化值可能导致数据异常
 * @see validation_result_t
 * @see validate_scaled_value
 * @see validate_short_float_value
 */
validation_result_t validate_normalized_value(s16 value);

/**
 * @brief 验证标度化值
 * @details 验证标度化值是否符合104协议规范。标度化值用于表示
 *          经过标度变换的测量值，通常用于遥测数据。
 * 
 * @param value 标度化值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示标度化值有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 标度化值需要根据标度因子进行转换
 * @warning 超出范围的标度化值可能导致数据异常
 * @see validation_result_t
 * @see validate_normalized_value
 * @see validate_short_float_value
 */
validation_result_t validate_scaled_value(s16 value);

/**
 * @brief 验证短浮点值
 * @details 验证短浮点值是否符合104协议规范。短浮点值用于表示
 *          高精度的测量值，通常用于遥测数据。
 * 
 * @param value 短浮点值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示短浮点值有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 短浮点值需要检查是否为有效数值
 * @warning 无效的浮点值（如NaN、无穷大）会导致数据异常
 * @see validation_result_t
 * @see validate_normalized_value
 * @see validate_scaled_value
 */
validation_result_t validate_short_float_value(float value);

/* ==================== 序列号验证 ==================== */

/**
 * @brief 验证发送序列号
 * @details 验证发送序列号是否符合104协议规范。发送序列号用于
 *          标识发送的I格式APDU，确保数据的有序传输。
 * 
 * @param send_seq 发送序列号值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示发送序列号有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 发送序列号必须在有效范围内（0-32767）
 * @warning 无效的发送序列号会导致APDU被丢弃
 * @see validation_result_t
 * @see validate_recv_sequence
 * @see validate_sequence_continuity
 */
validation_result_t validate_send_sequence(u16 send_seq);

/**
 * @brief 验证接收序列号
 * @details 验证接收序列号是否符合104协议规范。接收序列号用于
 *          标识期望接收的下一个I格式APDU，确保数据的有序接收。
 * 
 * @param recv_seq 接收序列号值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示接收序列号有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 接收序列号必须在有效范围内（0-32767）
 * @warning 无效的接收序列号会导致APDU被丢弃
 * @see validation_result_t
 * @see validate_send_sequence
 * @see validate_sequence_continuity
 */
validation_result_t validate_recv_sequence(u16 recv_seq);

/**
 * @brief 验证序列号连续性
 * @details 验证序列号的连续性是否符合104协议规范。序列号连续性
 *          检查用于确保数据的有序传输，防止数据丢失或重复。
 * 
 * @param expected_seq 期望序列号值
 * @param actual_seq 实际序列号值
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示序列号连续，false表示不连续
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 序列号连续性检查是104协议的重要特性
 * @warning 序列号不连续可能导致数据丢失或重复
 * @see validation_result_t
 * @see validate_send_sequence
 * @see validate_recv_sequence
 */
validation_result_t validate_sequence_continuity(u16 expected_seq, u16 actual_seq);

/* ==================== 缓冲区验证 ==================== */

/**
 * @brief 验证缓冲区边界
 * @details 验证缓冲区访问是否越界。该函数检查从指定偏移量开始，
 *          读取指定长度数据是否会超出缓冲区边界。这是防止缓冲区
 *          溢出攻击的重要安全检查。
 * 
 * @param buffer 缓冲区指针，不能为NULL
 * @param buffer_size 缓冲区总大小（字节）
 * @param offset 访问偏移量（字节）
 * @param required_length 需要读取的长度（字节）
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示边界检查通过，false表示越界
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 边界检查包括NULL指针检查和越界检查
 * @warning 缓冲区越界访问可能导致程序崩溃或安全漏洞
 * @see validation_result_t
 * @see validate_buffer_not_null
 */
validation_result_t validate_buffer_boundary(const u8* buffer, u32 buffer_size,
                                           u32 offset, u32 required_length);

/**
 * @brief 验证缓冲区不为空
 * @details 验证缓冲区指针不为NULL且缓冲区大小大于0。该函数是
 *          缓冲区验证的基础检查，确保后续的缓冲区操作是安全的。
 * 
 * @param buffer 缓冲区指针，不能为NULL
 * @param buffer_size 缓冲区大小（字节），必须大于0
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示缓冲区有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 检查包括NULL指针检查和大小检查
 * @warning 空缓冲区可能导致后续操作失败
 * @see validation_result_t
 * @see validate_buffer_boundary
 */
validation_result_t validate_buffer_not_null(const u8* buffer, u32 buffer_size);

/* ==================== 综合验证 ==================== */

/**
 * @brief 验证完整的APDU
 * @details 验证完整的APDU数据是否符合104协议规范。该函数会检查
 *          APDU的格式、长度、控制域、ASDU等所有组成部分的有效性。
 *          这是APDU验证的综合检查函数。
 * 
 * @param data APDU数据缓冲区，不能为NULL
 * @param length APDU数据长度（字节），必须大于等于6
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示APDU有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 验证包括格式、长度、控制域、ASDU等所有检查
 * @warning 无效的APDU会导致协议通信失败
 * @see validation_result_t
 * @see validate_apdu_format
 * @see validate_complete_asdu
 */
validation_result_t validate_complete_apdu(const u8* data, u32 length);

/**
 * @brief 验证完整的ASDU
 * @details 验证完整的ASDU数据是否符合104协议规范。该函数会检查
 *          ASDU的格式、类型标识、可变结构限定词、传送原因、公共地址、
 *          信息对象地址、信息对象数据等所有组成部分的有效性。
 * 
 * @param data ASDU数据缓冲区，不能为NULL
 * @param length ASDU数据长度（字节），必须大于等于6
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示ASDU有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 验证包括格式、类型标识、VSQ、COT、地址、数据等所有检查
 * @warning 无效的ASDU会导致数据解析失败
 * @see validation_result_t
 * @see validate_asdu_format
 * @see validate_complete_apdu
 */
validation_result_t validate_complete_asdu(const u8* data, u32 length);

/**
 * @brief 验证信息对象数据
 * @details 根据类型标识验证信息对象数据的有效性。该函数会根据不同的
 *          类型标识（如遥测、遥信、遥控等）对相应的数据格式进行验证，
 *          包括数据长度、数据范围、品质描述等。
 * 
 * @param type_id 类型标识，取值范围1-127
 * @param data 信息对象数据缓冲区，不能为NULL
 * @param length 数据长度（字节），必须大于0
 * 
 * @return 验证结果结构体
 *         - is_valid: true表示信息对象数据有效，false表示无效
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 验证包括类型标识、数据长度、数据格式、品质描述等检查
 * @warning 无效的信息对象数据会导致数据解析错误
 * @see validation_result_t
 * @see validate_type_id
 * @see validate_complete_asdu
 */
validation_result_t validate_info_object_data(u8 type_id, const u8* data, u32 length);

/* ==================== 验证工具函数 ==================== */

/**
 * @brief 创建验证结果
 * @details 创建验证结果结构体。该函数是验证工具函数，用于统一创建
 *          验证结果，确保验证结果格式的一致性。可以根据验证是否成功
 *          创建相应的结果结构体。
 * 
 * @param is_valid 验证是否成功，true表示成功，false表示失败
 * @param error 错误码，当is_valid为false时使用
 * @param message 错误消息，当is_valid为false时使用，可以为NULL
 * 
 * @return 验证结果结构体
 *         - is_valid: 与输入参数相同
 *         - error: 错误码（当is_valid为false时）
 *         - message: 错误消息（当is_valid为false时）
 * 
 * @note 该函数是线程安全的
 * @note 当is_valid为true时，error和message参数被忽略
 * @see validation_result_t
 * @see create_success_result
 * @see create_failure_result
 */
validation_result_t create_validation_result(bool is_valid, protocol_error_t error, const char* message);

/**
 * @brief 创建成功验证结果
 * @details 创建表示验证成功的验证结果结构体。该函数是验证工具函数，
 *          用于快速创建成功验证结果，is_valid字段为true，error和message
 *          字段为默认值。
 * 
 * @return 验证结果结构体
 *         - is_valid: true（表示验证成功）
 *         - error: PROTOCOL_SUCCESS
 *         - message: "Validation successful"
 * 
 * @note 该函数是线程安全的
 * @note 返回的结果表示验证成功
 * @see validation_result_t
 * @see create_failure_result
 * @see create_validation_result
 */
validation_result_t create_success_result(void);

/**
 * @brief 创建失败验证结果
 * @details 创建表示验证失败的验证结果结构体。该函数是验证工具函数，
 *          用于快速创建失败验证结果，is_valid字段为false，error和message
 *          字段为指定的错误信息。
 * 
 * @param error 错误码，不能为PROTOCOL_SUCCESS
 * @param message 错误消息，可以为NULL（使用默认消息）
 * 
 * @return 验证结果结构体
 *         - is_valid: false（表示验证失败）
 *         - error: 指定的错误码
 *         - message: 指定的错误消息或默认消息
 * 
 * @note 该函数是线程安全的
 * @note 返回的结果表示验证失败
 * @see validation_result_t
 * @see create_success_result
 * @see create_validation_result
 */
validation_result_t create_failure_result(protocol_error_t error, const char* message);

/**
 * @brief 检查验证结果是否成功
 * @details 检查验证结果是否表示验证成功。该函数是验证工具函数，
 *          用于快速判断验证结果的状态，避免直接访问结构体字段。
 * 
 * @param result 验证结果指针，不能为NULL
 * 
 * @return 验证结果状态
 *         - true: 验证成功
 *         - false: 验证失败或结果指针为NULL
 * 
 * @note 该函数是线程安全的
 * @note 如果result为NULL，返回false
 * @see validation_result_t
 * @see get_validation_error_message
 */
bool is_validation_success(const validation_result_t* result);

/**
 * @brief 获取验证结果错误消息
 * @details 获取验证结果中的错误消息。该函数是验证工具函数，
 *          用于获取验证失败时的详细错误信息，便于调试和日志记录。
 * 
 * @param result 验证结果指针，不能为NULL
 * 
 * @return 错误消息字符串
 *         - 验证失败：返回错误消息字符串
 *         - 验证成功：返回"Validation successful"
 *         - 结果指针为NULL：返回"Invalid result pointer"
 * 
 * @note 该函数是线程安全的
 * @note 返回的字符串是静态常量，不需要释放
 * @see validation_result_t
 * @see is_validation_success
 */
const char* get_validation_error_message(const validation_result_t* result);

/* ==================== 协议验证器管理函数 ==================== */

/**
 * @brief 创建协议验证器
 * @details 创建新的协议验证器实例。该函数会分配内存并初始化验证器，
 *          包括设置默认配置、初始化内部状态等。验证器用于执行各种
 *          协议数据验证操作。
 * 
 * @return 协议验证器指针
 *         - 成功：返回新创建的验证器指针
 *         - 失败：返回NULL（内存分配失败或初始化失败）
 * 
 * @note 该函数是线程安全的
 * @note 创建的验证器需要调用destroy_protocol_validator释放
 * @warning 内存分配失败时会返回NULL
 * @see protocol_validator_t
 * @see destroy_protocol_validator
 */
protocol_validator_t* create_protocol_validator(void);

/**
 * @brief 销毁协议验证器
 * @details 销毁协议验证器实例并释放相关资源。该函数会清理验证器的
 *          内部状态、释放分配的内存等。销毁后，验证器指针将不再有效。
 * 
 * @param validator 协议验证器指针，可以为NULL
 * 
 * @note 该函数是线程安全的
 * @note 如果validator为NULL，函数会安全返回，不执行任何操作
 * @note 销毁后，验证器指针将不再有效，不应再次使用
 * @see protocol_validator_t
 * @see create_protocol_validator
 */
void destroy_protocol_validator(protocol_validator_t* validator);

/**
 * @brief 初始化协议验证器
 * @details 初始化协议验证器的内部状态和配置。该函数会设置验证器的
 *          默认配置、初始化内部数据结构、设置验证规则等。验证器必须
 *          在创建后调用此函数进行初始化才能正常使用。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 初始化成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器指针为NULL
 *         - PROTOCOL_ERROR_INIT_FAILED: 初始化失败
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须先创建再初始化
 * @warning 未初始化的验证器不能正常使用
 * @see protocol_validator_t
 * @see create_protocol_validator
 * @see destroy_protocol_validator
 */
protocol_error_t init_protocol_validator(protocol_validator_t* validator);

/**
 * @brief 验证APDU消息
 * @details 验证APDU消息的完整性和有效性。该函数会根据APDU的格式类型
 *          （I格式、S格式、U格式）调用相应的验证函数，检查APDU的格式、
 *          长度、控制域、ASDU等所有组成部分的有效性。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * @param apdu APDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器或APDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_FORMAT: APDU格式无效
 *         - PROTOCOL_ERROR_INVALID_LENGTH: APDU长度无效
 *         - PROTOCOL_ERROR_INVALID_CONTROL: 控制域无效
 *         - PROTOCOL_ERROR_INVALID_ASDU: ASDU无效
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须已初始化
 * @warning 无效的APDU会导致协议通信失败
 * @see protocol_validator_t
 * @see apdu_t
 * @see validate_i_format_apdu
 * @see validate_s_format_apdu
 * @see validate_u_format_apdu
 */
protocol_error_t validate_apdu_message(protocol_validator_t* validator, const apdu_t* apdu);

/* ==================== 内部验证函数声明 ==================== */

/**
 * @brief 验证I格式APDU
 * @details 验证I格式APDU的有效性。I格式APDU用于传输信息数据，包含
 *          发送序列号、接收序列号和ASDU。该函数会检查I格式APDU的格式、
 *          序列号、ASDU等组成部分的有效性。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * @param apdu APDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器或APDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_FORMAT: I格式APDU格式无效
 *         - PROTOCOL_ERROR_INVALID_SEQUENCE: 序列号无效
 *         - PROTOCOL_ERROR_INVALID_ASDU: ASDU无效
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须已初始化
 * @note I格式APDU必须包含有效的ASDU
 * @warning 无效的I格式APDU会导致数据丢失
 * @see protocol_validator_t
 * @see apdu_t
 * @see validate_apdu_message
 */
protocol_error_t validate_i_format_apdu(protocol_validator_t* validator, const apdu_t* apdu);

/**
 * @brief 验证S格式APDU
 * @details 验证S格式APDU的有效性。S格式APDU用于确认接收到的I格式APDU，
 *          只包含接收序列号，不包含ASDU。该函数会检查S格式APDU的格式
 *          和接收序列号的有效性。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * @param apdu APDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器或APDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_FORMAT: S格式APDU格式无效
 *         - PROTOCOL_ERROR_INVALID_SEQUENCE: 接收序列号无效
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须已初始化
 * @note S格式APDU不包含ASDU，只用于确认
 * @warning 无效的S格式APDU会导致确认失败
 * @see protocol_validator_t
 * @see apdu_t
 * @see validate_apdu_message
 */
protocol_error_t validate_s_format_apdu(protocol_validator_t* validator, const apdu_t* apdu);

/**
 * @brief 验证U格式APDU
 * @details 验证U格式APDU的有效性。U格式APDU用于控制功能，如STARTDT、
 *          STOPDT、TESTFR等，不包含序列号和ASDU。该函数会检查U格式APDU
 *          的格式和控制域的有效性。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * @param apdu APDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器或APDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_FORMAT: U格式APDU格式无效
 *         - PROTOCOL_ERROR_INVALID_CONTROL: 控制域无效
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须已初始化
 * @note U格式APDU不包含序列号和ASDU，只用于控制
 * @warning 无效的U格式APDU会导致控制功能失败
 * @see protocol_validator_t
 * @see apdu_t
 * @see validate_apdu_message
 */
protocol_error_t validate_u_format_apdu(protocol_validator_t* validator, const apdu_t* apdu);

/**
 * @brief 验证ASDU消息
 * @details 验证ASDU消息的完整性和有效性。该函数会检查ASDU的格式、
 *          类型标识、可变结构限定词、传送原因、公共地址、信息对象地址、
 *          信息对象数据等所有组成部分的有效性。
 * 
 * @param validator 协议验证器指针，不能为NULL
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 验证器或ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_FORMAT: ASDU格式无效
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识无效
 *         - PROTOCOL_ERROR_INVALID_VSQ: 可变结构限定词无效
 *         - PROTOCOL_ERROR_INVALID_COT: 传送原因无效
 *         - PROTOCOL_ERROR_INVALID_ADDRESS: 地址无效
 *         - PROTOCOL_ERROR_INVALID_DATA: 信息对象数据无效
 * 
 * @note 该函数是线程安全的
 * @note 验证器必须已初始化
 * @note ASDU验证包括所有组成部分的检查
 * @warning 无效的ASDU会导致数据解析失败
 * @see protocol_validator_t
 * @see asdu_t
 * @see validate_apdu_message
 */
protocol_error_t validate_asdu_message(protocol_validator_t* validator, const asdu_t* asdu);

/**
 * @brief 从APDU中提取ASDU
 * @param apdu APDU结构指针
 * @param asdu ASDU结构指针
 * @return 协议错误码
 */
/* extract_asdu_from_apdu is declared in apdu_parser.h */

/**
 * @brief 释放ASDU资源
 * @param asdu ASDU结构指针
 */
/* free_asdu is declared in apdu_parser.h */

/**
 * @brief 验证ASDU类型
 * @param asdu ASDU结构指针
 * @return 协议错误码
 */
/* validate_asdu_type is declared in asdu_parser.h */

/**
 * @brief 验证ASDU数据
 * @param asdu ASDU结构指针
 * @return 协议错误码
 */
/* validate_asdu_data is declared in asdu_parser.h */

/**
 * @brief 验证单点信息ASDU
 * @details 验证单点信息ASDU的有效性。单点信息用于表示开关状态等
 *          二进制信息，包含单点信息品质描述符（SIQ）。该函数会检查
 *          单点信息ASDU的格式、类型标识、数据长度、品质描述等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是单点信息类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_SIQ: 单点信息品质描述符无效
 * 
 * @note 该函数是线程安全的
 * @note 单点信息ASDU的数据长度必须为1字节
 * @warning 无效的单点信息ASDU会导致状态解析错误
 * @see asdu_t
 * @see validate_double_point_asdu
 * @see validate_measurement_asdu
 */
protocol_error_t validate_single_point_asdu(const asdu_t* asdu);

/**
 * @brief 验证双点信息ASDU
 * @details 验证双点信息ASDU的有效性。双点信息用于表示具有中间状态的
 *          开关信息，包含双点信息品质描述符（DIQ）。该函数会检查双点
 *          信息ASDU的格式、类型标识、数据长度、品质描述等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是双点信息类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_DIQ: 双点信息品质描述符无效
 * 
 * @note 该函数是线程安全的
 * @note 双点信息ASDU的数据长度必须为1字节
 * @warning 无效的双点信息ASDU会导致状态解析错误
 * @see asdu_t
 * @see validate_single_point_asdu
 * @see validate_measurement_asdu
 */
protocol_error_t validate_double_point_asdu(const asdu_t* asdu);

/**
 * @brief 验证测量值ASDU
 * @details 验证测量值ASDU的有效性。测量值用于表示模拟量数据，如电压、
 *          电流、功率等，包含测量值品质描述符（QDS）和测量值数据。
 *          该函数会检查测量值ASDU的格式、类型标识、数据长度、品质描述等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是测量值类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_QDS: 测量值品质描述符无效
 *         - PROTOCOL_ERROR_INVALID_MEASUREMENT: 测量值数据无效
 * 
 * @note 该函数是线程安全的
 * @note 测量值ASDU的数据长度根据类型标识确定
 * @warning 无效的测量值ASDU会导致数据解析错误
 * @see asdu_t
 * @see validate_single_point_asdu
 * @see validate_double_point_asdu
 */
protocol_error_t validate_measurement_asdu(const asdu_t* asdu);

/**
 * @brief 验证单命令ASDU
 * @details 验证单命令ASDU的有效性。单命令用于控制单点设备，如开关、
 *          继电器等，包含单命令控制对象（SCO）。该函数会检查单命令
 *          ASDU的格式、类型标识、数据长度、控制对象等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是单命令类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_SCO: 单命令控制对象无效
 * 
 * @note 该函数是线程安全的
 * @note 单命令ASDU的数据长度必须为1字节
 * @warning 无效的单命令ASDU会导致控制失败
 * @see asdu_t
 * @see validate_double_command_asdu
 * @see validate_total_interrogation_asdu
 */
protocol_error_t validate_single_command_asdu(const asdu_t* asdu);

/**
 * @brief 验证双命令ASDU
 * @details 验证双命令ASDU的有效性。双命令用于控制双点设备，如具有
 *          中间状态的开关等，包含双命令控制对象（DCO）。该函数会检查
 *          双命令ASDU的格式、类型标识、数据长度、控制对象等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是双命令类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_DCO: 双命令控制对象无效
 * 
 * @note 该函数是线程安全的
 * @note 双命令ASDU的数据长度必须为1字节
 * @warning 无效的双命令ASDU会导致控制失败
 * @see asdu_t
 * @see validate_single_command_asdu
 * @see validate_total_interrogation_asdu
 */
protocol_error_t validate_double_command_asdu(const asdu_t* asdu);

/**
 * @brief 验证总召唤ASDU
 * @details 验证总召唤ASDU的有效性。总召唤用于请求所有数据，包含
 *          总召唤限定词（QOI）。该函数会检查总召唤ASDU的格式、类型标识、
 *          数据长度、限定词等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是总召唤类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_QOI: 总召唤限定词无效
 * 
 * @note 该函数是线程安全的
 * @note 总召唤ASDU的数据长度必须为1字节
 * @warning 无效的总召唤ASDU会导致数据请求失败
 * @see asdu_t
 * @see validate_single_command_asdu
 * @see validate_double_command_asdu
 */
protocol_error_t validate_total_interrogation_asdu(const asdu_t* asdu);

/**
 * @brief 验证时钟同步ASDU
 * @details 验证时钟同步ASDU的有效性。时钟同步用于同步系统时间，包含
 *          时间戳信息。该函数会检查时钟同步ASDU的格式、类型标识、
 *          数据长度、时间戳等。
 * 
 * @param asdu ASDU结构指针，不能为NULL
 * 
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: ASDU指针为NULL
 *         - PROTOCOL_ERROR_INVALID_TYPE_ID: 类型标识不是时钟同步类型
 *         - PROTOCOL_ERROR_INVALID_DATA_LENGTH: 数据长度无效
 *         - PROTOCOL_ERROR_INVALID_TIMESTAMP: 时间戳无效
 * 
 * @note 该函数是线程安全的
 * @note 时钟同步ASDU的数据长度必须为7字节（CP56Time2a格式）
 * @warning 无效的时钟同步ASDU会导致时间同步失败
 * @see asdu_t
 * @see validate_total_interrogation_asdu
 */
protocol_error_t validate_clock_sync_asdu(const asdu_t* asdu);

#ifdef __cplusplus
}
#endif

#endif /* PROTOCOL_VALIDATOR_H */
